Coverage Report

Created: 2024-12-26 12:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
D:\a\tools.proto\tools.proto\compiler\src\gen\base\message_common.rs
Line
Count
Source
1
// Copyright (c) 2024, BlockProject 3D
2
//
3
// All rights reserved.
4
//
5
// Redistribution and use in source and binary forms, with or without modification,
6
// are permitted provided that the following conditions are met:
7
//
8
//     * Redistributions of source code must retain the above copyright notice,
9
//       this list of conditions and the following disclaimer.
10
//     * Redistributions in binary form must reproduce the above copyright notice,
11
//       this list of conditions and the following disclaimer in the documentation
12
//       and/or other materials provided with the distribution.
13
//     * Neither the name of BlockProject 3D nor the names of its contributors
14
//       may be used to endorse or promote products derived from this software
15
//       without specific prior written permission.
16
//
17
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29
use crate::compiler::message::{Field, FieldType, Referenced};
30
use crate::compiler::util::types::TypeMapper;
31
use crate::gen::base::map::TypePathMapper;
32
use crate::gen::base::message::Utilities;
33
use crate::gen::base::Error;
34
use crate::gen::template::Template;
35
use std::borrow::Cow;
36
37
pub struct MaybeOptional<'b, 'a, 'fragment, 'variable> {
38
    template: &'a Template<'fragment, 'variable>,
39
    function: &'b str,
40
    optional: bool,
41
}
42
43
impl<'b, 'a, 'fragment, 'variable> MaybeOptional<'b, 'a, 'fragment, 'variable> {
44
154
    pub fn new(field: &Field, function: &'b str, template: &'a Template<'fragment, 'variable>) -> Self {
45
154
        Self {
46
154
            template,
47
154
            function,
48
154
            optional: field.optional,
49
154
        }
50
154
    }
51
52
154
    pub fn gen<'c>(self, type_name: impl Into<Cow<'c, str>>) -> Result<Cow<'c, str>, Error>
53
154
    where
54
154
        'a: 'c,
55
154
    {
56
154
        if self.optional {
  Branch (56:12): [True: 7, False: 45]
  Branch (56:12): [True: 16, False: 76]
  Branch (56:12): [True: 0, False: 10]
  Branch (56:12): [Folded - Ignored]
57
23
            self.template
58
23
                .scope()
59
23
                .var("msg_type", type_name)
60
23
                .render(self.function, &["option"])
61
23
                .map(|v| v.into())
62
23
                .map_err(Error::Codec)
63
        } else {
64
131
            Ok(type_name.into())
65
        }
66
154
    }
67
}
68
69
154
pub fn generate_field_type_inline<'a, U: Utilities, T: TypeMapper>(
70
154
    field: &'a Field,
71
154
    template: &'a Template,
72
154
    type_path_map: &'a TypePathMapper<T>,
73
154
    function: &str,
74
154
) -> Result<Cow<'a, str>, Error> {
75
154
    let optional = MaybeOptional::new(field, function, template);
76
154
    let msg_type = match &field.ty {
77
10
        FieldType::Fixed(ty) => optional.gen(U::get_value_type_inline(field.endianness, ty.ty)),
78
38
        FieldType::Ref(v) => match v {
79
31
            Referenced::Struct(v) => optional.gen(type_path_map.get(v)),
80
7
            Referenced::Message(v) => optional.gen(type_path_map.get(v)),
81
        },
82
29
        FieldType::Buffer => optional.gen(template.scope().render(function, &["buffer"]).map_err(Error::Codec)
?0
),
83
17
        FieldType::SizedBuffer(v) => optional.gen(
84
17
            template
85
17
                .scope()
86
17
                .var("codec", U::get_value_type(field.endianness, v.ty))
87
17
                .render(function, &["sized_buffer"])
88
17
                .map_err(Error::Codec)
?0
,
89
        ),
90
8
        FieldType::FixedContainer(v) => optional.gen(
91
8
            template
92
8
                .scope()
93
8
                .var("codec", U::get_value_type(field.endianness, v.ty))
94
8
                .var("type_name", type_path_map.get(&v.item_type))
95
8
                .render(function, &["fixed_container"])
96
8
                .map_err(Error::Codec)
?0
,
97
        ),
98
14
        FieldType::Union(v) => optional.gen(type_path_map.get(&v.r)),
99
26
        FieldType::Container(v) => match v.nested {
100
21
            false => optional.gen(
101
21
                template
102
21
                    .scope()
103
21
                    .var("codec", U::get_value_type(field.endianness, v.ty))
104
21
                    .var("type_name", type_path_map.get(&v.item_type))
105
21
                    .render(function, &["unsized_container"])
106
21
                    .map_err(Error::Codec)
?0
,
107
            ),
108
5
            true => optional.gen(
109
5
                template
110
5
                    .scope()
111
5
                    .var("codec", U::get_value_type(field.endianness, v.ty))
112
5
                    .var("type_name", type_path_map.get(&v.item_type))
113
5
                    .render(function, &["container"])
114
5
                    .map_err(Error::Codec)
?0
,
115
            ),
116
        },
117
0
        FieldType::Payload => optional.gen(template.scope().render(function, &["payload"]).map_err(Error::Codec)?),
118
12
        FieldType::SizedContainer(v) => optional.gen(
119
12
            template
120
12
                .scope()
121
12
                .var("codec", U::get_value_type(field.endianness, v.ty))
122
12
                .var("type_name", type_path_map.get(&v.item_type))
123
12
                .var("size_codec", U::get_value_type(field.endianness, v.size_ty))
124
12
                .render(function, &["sized_container"])
125
12
                .map_err(Error::Codec)
?0
,
126
        ),
127
    };
128
154
    msg_type
129
154
}